// # axios核心封装
import axios, {
  type AxiosInstance,
  type AxiosRequestConfig,
  type AxiosResponse,
  type AxiosError
} from "axios";
import { 
  type BaseResponse, 
  type RequestConfig 
} from "@/types/request"
// @ts-ignore
import Cookies from "js-cookie";
import { envConfig } from "@/config/env";

class Request {

private instance: AxiosInstance;

constructor(config: RequestConfig) {
  this.instance = axios.create({
    baseURL: envConfig.API_BASE_URL,
    timeout: 60000,
    ...config
  });
  this.setupInterceptors();
}

// 泛型请求方法
public async request<T = any>(config: RequestConfig): Promise<BaseResponse<T>> {
  try {
    const response = await this.instance.request<BaseResponse<T>>(config);
    return response.data;
  } catch (err) {
    return this.handleError(err as AxiosError<BaseResponse>);
  }
}

// 拦截器配置
private setupInterceptors() {
  this.instance.interceptors.request.use(
    // @ts-ignore
    (config: AxiosRequestConfig) => {
      // console.log('📤 请求拦截器 - 发送请求:', {
      //   method: config.method?.toUpperCase(),
      //   url: config.url,
      //   baseURL: config.baseURL,
      //   data: config.data
      // });
      
      // 临时禁用Authorization头部，专注于解决基本连接问题
      // console.log('ℹ️ 临时禁用Authorization头部进行测试');
      
      const token = Cookies.get("token") || localStorage.getItem('token');
      if (token) {
        try {
          // 确保token只包含ASCII字符
          const asciiToken = token.replace(/[^\x00-\x7F]/g, "");
          if (asciiToken && asciiToken.length > 0) {
            (config.headers as Record<string, any>).Authorization = `Bearer ${asciiToken}`;
            console.log('✅ 已设置Authorization头部');
          } else {
            console.warn('⚠️ Token包含非ASCII字符，已跳过Authorization头部');
          }
        } catch (error) {
          console.error('❌ 设置Authorization头部失败:', error);
        }
      } else {
        console.log('ℹ️ 未找到token，跳过Authorization头部');
      }
      return config;
    },
    (error: AxiosError) => Promise.reject(error)
  );

  this.instance.interceptors.response.use(
    (response: AxiosResponse<BaseResponse>) => {
      // console.log('📥 响应拦截器 - 响应数据:', {
      //   status: response.status,
      //   statusText: response.statusText,
      //   data: response.data,
      //   url: response.config?.url
      // });
      
      if (response.data.code !== 200) {
        // console.error('❌ 响应拦截器 - 业务错误:', response.data);
        return Promise.reject(response.data);
      }
      return response;
    },
    (error: AxiosError<BaseResponse>) => {
      console.error('❌ 响应拦截器 - 网络错误:', error);
      this.handleError(error);
      return Promise.reject(error);
    }
  );
}

// 统一错误处理
private handleError(error: AxiosError<BaseResponse>): never {
  console.error('🔍 详细错误信息:', {
    message: error.message,
    status: error.response?.status,
    statusText: error.response?.statusText,
    data: error.response?.data,
    config: {
      url: error.config?.url,
      method: error.config?.method,
      baseURL: error.config?.baseURL,
      headers: error.config?.headers
    }
  });
  
  const statusMap: Record<number, string> = {
    401: "请重新登录!",
    403: "Access denied",
    404: "资源未找到!",
    500: "服务异常请联系管理员!"
  };
  
  // 优先使用后端返回的错误信息
  const msg = error.response?.data?.msg 
    || error.response?.data?.message 
    || statusMap[error.response?.status || 500]
    || error.message
    || "未知错误!";
    
  throw new Error(msg);
}

// 快捷方法（带泛型）
/**
 * 封装 GET 请求方法（带泛型类型安全）
 * @param url 请求路径（必填）
 * @param config 请求配置（可选），包含 headers、params 等 Axios 原生配置
 * @returns Promise<BaseResponse<T>> 包含泛型类型 T 的响应结构
 */
public get<T = any>(
  url: string,
  config?: RequestConfig
): Promise<BaseResponse<T>> {
  return this.request<T>({ ...config, method: "GET", url });
}

/**
 * 封装 POST 请求方法（带泛型类型安全）
 * @param url 请求路径（必填）
 * @param data 请求体数据（可选）
 * @param config 请求配置（可选），包含 headers、timeout 等扩展配置
 * @returns Promise<BaseResponse<T>> 包含泛型类型 T 的响应结构
 */
public post<T = any>(
  url: string,
  data?: any,
  config?: RequestConfig
): Promise<BaseResponse<T>> {
  return this.request<T>({ ...config, method: "POST", url, data })
}

/**
 * 封装 PUT 请求方法（带泛型类型安全）
 * @param url 请求路径（必填）
 * @param data 请求体数据（可选）
 * @param config 请求配置（可选），包含 headers、timeout 等扩展配置
 * @returns Promise<BaseResponse<T>> 包含泛型类型 T 的响应结构
 */
public put<T = any>(
  url: string,
  data?: any,
  config?: RequestConfig
): Promise<BaseResponse<T>> {
  return this.request<T>({ ...config, method: "PUT", url, data })
}

/**
 * 封装 DELETE 请求方法（带泛型类型安全）
 * @param url 请求路径（必填）
 * @param config 请求配置（可选），包含 headers、params 等 Axios 原生配置
 * @returns Promise<BaseResponse<T>> 包含泛型类型 T 的响应结构
 */
public delete<T = any>(
  url: string,
  config?: RequestConfig
): Promise<BaseResponse<T>> {
  return this.request<T>({ ...config, method: "DELETE", url });
}

public async upload<T = any>(
  url: string,
  files: File | File[],          // 支持单文件或多文件上传
  data?: Record<string, any>,    // 其他表单数据
  config?: RequestConfig  & { timeout?: number }, // 基础配置  新增timeout类型
  options?: {                    // 上传专用配置
    fieldName?: string,          // 文件字段名（默认file）
    multipleField?: boolean      // 多文件是否使用多个字段（默认同名追加）
  }
): Promise<BaseResponse<T>> {
  // 新增文件类型校验
  // const validateFile = (file: File) => {
  //   if (!(file instanceof Blob)) {
  //     throw new Error(`无效文件类型: ${file.name}`);
  //   }
  //   if (!file.type.startsWith('image/')) {
  //     throw new Error(`仅支持图片格式: ${file.name}`);
  //   }
  // };

  const formData = new FormData();// 创建FormData对象
  const fieldName = options?.fieldName || 'file';// 处理文件字段名称
  const isMultipleField = options?.multipleField || false;

  // 校验文件参数
  if (!files || (Array.isArray(files) && files.length === 0)) {
    throw new Error('上传文件不能为空');
  }

  const filesArray = Array.isArray(files) ? files : [files];// 处理文件列表（统一转为数组）

  // 添加文件到表单
  filesArray.forEach((file, index) => {
    const finalField = isMultipleField ? `${fieldName}[${index}]` : fieldName;
    formData.append(finalField, file, file.name);
  });

  // 添加其他表单数据
  if (data) {
    Object.entries(data).forEach(([key, value]) => {
      if (Array.isArray(value)) {
        value.forEach(v => formData.append(`${key}[]`, v));
      } else if (value instanceof Blob) {
        formData.append(key, value);
      } else {
        formData.append(key, String(value));
      }
    });
  }

  // 合并配置（重点处理Content-Type）
  const mergedConfig: RequestConfig = {
    ...config,
    timeout: config?.timeout || 300000, // 默认5分钟超时
    headers: {
      ...config?.headers,
      // 注意：使用FormData时不要设置Content-Type，浏览器会自动添加带boundary的格式
    },
    data: formData
  };

  // 调用已有的post方法
  //return this.post<T>(url, formData, mergedConfig);
  try {
    const response = await this.post<T>(url, formData, mergedConfig);
    return response;
  } catch (error) {
    // 统一错误格式
    return {
      code: 500,
      msg: error,
      data: null as T
    };
  }
}

public async uploadExcel<T = any>(
  url: string,
  files: File | File[],          // 支持单文件或多文件上传
  data?: Record<string, any>,    // 其他表单数据
  config?: RequestConfig  & { timeout?: number }, // 基础配置  新增timeout类型
  options?: {                    // 上传专用配置
    fieldName?: string,          // 文件字段名（默认file）
    multipleField?: boolean      // 多文件是否使用多个字段（默认同名追加）
  }
): Promise<BaseResponse<T>> {

  const formData = new FormData();// 创建FormData对象
  const fieldName = options?.fieldName || 'file';// 处理文件字段名称
  const isMultipleField = options?.multipleField || false;

  // 校验文件参数
  if (!files || (Array.isArray(files) && files.length === 0)) {
    throw new Error('上传文件不能为空');
  }

  const filesArray = Array.isArray(files) ? files : [files];// 处理文件列表（统一转为数组）

  // 添加文件到表单
  // filesArray.forEach((file, index) => {
  //   const finalField = isMultipleField ? `${fieldName}[${index}]` : fieldName;
  //   formData.append(finalField, file, file.name);
  // });

  filesArray.forEach((file, index) => {
    const fieldNames = ['excel_first', 'excel_second'];
    formData.append(fieldNames[index], file, file.name);
  });

  // 添加其他表单数据
  if (data) {
    Object.entries(data).forEach(([key, value]) => {
      if (Array.isArray(value)) {
        value.forEach(v => formData.append(`${key}[]`, v));
      } else if (value instanceof Blob) {
        formData.append(key, value);
      } else {
        formData.append(key, String(value));
      }
    });
  }

  // 合并配置（重点处理Content-Type）
  const mergedConfig: RequestConfig = {
    ...config,
    timeout: config?.timeout || 300000, // 默认5分钟超时
    headers: {
      ...config?.headers,
      // 注意：使用FormData时不要设置Content-Type，浏览器会自动添加带boundary的格式
    },
    data: formData
  };

  // 调用已有的post方法
  //return this.post<T>(url, formData, mergedConfig);
  try {
    const response = await this.post<T>(url, formData, mergedConfig);
    return response;
  } catch (error) {
    // 统一错误格式
    return {
      code: 500,
      msg: error,
      data: null as T
    };
  }
}

}


export const request = new Request({})

// 为了保持向后兼容，也导出为默认导出
export default request 